import { AfterViewInit, Component, OnInit, TemplateRef } from '@angular/core';
import { FormBuilder, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
import { NzMessageService } from 'ng-zorro-antd/message';
import { NzModalService } from 'ng-zorro-antd/modal';
import { ApiService } from 'src/app/services/api.service';
import { MenuDto } from 'src/app/models/sys/menu.dto';
import { MenuQueryParam } from 'src/app/models/param/menu-query.param';
import { Consts } from 'src/app/consts/consts';
import { BehaviorSubject } from 'rxjs';
import { NzTableQueryParams } from 'ng-zorro-antd/table';
import { EditMode } from 'src/app/models/enums/edit-mode.enum';
import { ClientDto } from 'src/app/models/sys/client.dto';
import { ClientQueryParam } from 'src/app/models/param/client-query.param';
import { ContentHeaderService } from 'src/app/services/content-header.service';

const MENU_NAME = "menuName";
const CLIENT_ID = "clientId";
const ENABLED = "enabled";

@Component({
  selector: 'app-menu',
  templateUrl: './menu.component.html',
  styleUrl: './menu.component.less'
})
export class MenuComponent implements OnInit, AfterViewInit {
  // 搜索栏
  searchForm!: UntypedFormGroup;
  submitted = false;
  clients: ClientDto[] = [];

  // Menu Table
  menus: MenuDto[] = [];
  pageIndex = 1;
  pageSize = 12;
  total = 0;

  mapOfExpandedData: { [key: number]: MenuDto[] } = {};

  // Modal
  modeSubject = new BehaviorSubject<{ mode: EditMode, menu?: MenuDto, parent?: MenuDto }>({ mode: EditMode.ADD, menu: undefined, parent: undefined });
  
  // 对话框title
  editTitle?: string;
  menuName?: string;

  // 详情
  menuSubject = new BehaviorSubject<MenuDto>(new MenuDto());

  constructor(private _api: ApiService,
    private _fb: FormBuilder,
    private _modal: NzModalService,
    private _message: NzMessageService,
    private _contentHeader: ContentHeaderService) { }

  ngAfterViewInit(): void {
    setTimeout(() => {
      this._contentHeader.header.next('权限管理');
    });
  }

  ngOnInit(): void {
    console.log('menu on init');
    this.createSearchForm();
    this.getClients();
    this.onSearch();
  }

  createSearchForm() {
    this.searchForm = this._fb.group({});
    this.searchForm.addControl(MENU_NAME, new UntypedFormControl('', [Validators.maxLength(20)]));
    this.searchForm.addControl(CLIENT_ID, new UntypedFormControl('', [Validators.maxLength(20)]));
    this.searchForm.addControl(ENABLED, new UntypedFormControl(''));
  }

  getClients() {
    const param = new ClientQueryParam();
    this._api.getClientList(param).subscribe((resp) => {
      if (resp.code == Consts.RESP_OK && resp.data) {
        this.clients = resp.data;
      }
    });
  }

  get fm() {
    return this.searchForm.controls;
  }

  onSearch() {
    this.resetPage();
    this.doSearch();
  }

  doSearch() {
    this.submitted = true;
    if (!this.searchForm.valid) {
      return;
    }

    const param = new MenuQueryParam();
    param.menuName = this.searchForm.get(MENU_NAME)?.value;
    param.enabled = this.searchForm.get(ENABLED)?.value;
    param.clientId = this.searchForm.get('clientId')?.value;
    param.withButton = 1;
    param.pageNum = this.pageIndex;
    param.pageSize = this.pageSize;

    this._api.getMenuTreePage(param).subscribe((resp) => {
      console.log('getMenuTreePage');
      if (resp.code == Consts.RESP_OK && resp.data) {
        this.menus = resp.data;
        this.total = resp.total;

        console.log('convert menus to table tree');
        this.mapOfExpandedData = {};
        this.menus.forEach(item => {
          this.mapOfExpandedData[item.menuId] = this.convertTreeToList(item);
        });

        this.submitted = false;
      }
    });
  }

  onUpdate(tplTitle: TemplateRef<object>, tplContent: TemplateRef<object>, menu: MenuDto) {
    this.editTitle = '编辑权限';
    this.menuName = menu.menuName;

    this._modal.create({
      nzTitle: tplTitle,
      nzContent: tplContent,
      nzFooter: null,
      nzMaskClosable: false,
      nzClosable: false,
      nzWidth: 800,
      nzOnOk: () => {
        console.log('client added');
      }
    });

    this.modeSubject.next({ mode: EditMode.EDIT, menu: menu, parent: undefined });
  }

  onCreate(tplTitle: TemplateRef<object>, tplContent: TemplateRef<object>, parent?: MenuDto) {
    this.editTitle = '创建权限';
    this.menuName = undefined;

    this._modal.create({
      nzTitle: tplTitle,
      nzContent: tplContent,
      nzFooter: null,
      nzMaskClosable: false,
      nzClosable: false,
      nzWidth: 800,
      nzOnOk: () => {
        console.log('client added');
      }
    });

    this.modeSubject.next({ mode: EditMode.ADD, menu: undefined, parent: parent });
  }

  onDetail(tplTitle: TemplateRef<object>, tplContent: TemplateRef<object>, menu: MenuDto) {
    this.editTitle = '权限详情';
    this.menuName = menu.menuName;

    this._modal.create({
      nzTitle: tplTitle,
      nzContent: tplContent,
      nzFooter: null,
      nzMaskClosable: false,
      nzClosable: false,
      nzWidth: 1024,
      nzOnOk: () => {
        console.log('groupType detail');
      }
    });

    this.menuSubject.next(menu);
  }

  onCreateBelow(tplTitle: TemplateRef<object>, tplContent: TemplateRef<object>, menu: MenuDto) {
    console.log(`create menu below ${menu.menuId}`);
    this.onCreate(tplTitle, tplContent, menu);
  }

  
  onDelete(id: number) {
    this._api.deleteMenu(id).subscribe((resp) => {
      if (resp.code == Consts.RESP_OK) {
        this._message.info("删除权限成功");
        this.onSearch();
      } else {
        this._message.warning("删除权限失败: " + resp.message);
      }
    });
  }

  onReset() {
    this.searchForm.get(MENU_NAME)?.setValue(undefined);
    this.searchForm.get(ENABLED)?.setValue(undefined);
    this.searchForm.get(CLIENT_ID)?.setValue(undefined);
  }

  // Tree ops
  convertTreeToList(root: MenuDto): MenuDto[] {
    const stack: MenuDto[] = [];
    const array: MenuDto[] = [];
    const hashMap = {};
    stack.push({ ...root, level: 0, expand: false });

    while (stack.length !== 0) {
      const node = stack.pop()!;
      this.visitNode(node, hashMap, array);
      if (node.children) {
        for (let i = node.children.length - 1; i >= 0; i--) {
          stack.push({ ...node.children[i], level: node.level! + 1, expand: false, parent: node });
        }
      }
    }

    return array;
  }

  visitNode(node: MenuDto, hashMap: { [key: number]: boolean }, array: MenuDto[]): void {
    if (!hashMap[node.menuId]) {
      hashMap[node.menuId] = true;
      array.push(node);
    }
  }

  collapse(array: MenuDto[], data: MenuDto, $event: boolean): void {
    if (!$event) {
      if (data.children) {
        data.children.forEach(d => {
          const target = array.find(a => a.menuId === d.menuId)!;
          target.expand = false;
          this.collapse(array, target, false);
        });
      } else {
        return;
      }
    }
  }

  onAddMenuEvent(result: boolean) {
    console.log(`add dept result ${result}`);
    if (result) {
      this.onSearch();
    }

    this._modal.closeAll();
  }

  resetPage() {
    this.pageIndex = 1;
    this.pageSize = 10;
  }

  onPageParamChange(params: NzTableQueryParams) {
    this.pageIndex = params.pageIndex;
    this.pageSize = params.pageSize;
    this.doSearch();
  }

  onDetailEvent(result: boolean) {
    this._modal.closeAll();
    console.log(`${result}`);
  }
}
